package com.xiuyou.tracksdk.tracksdk.protocol.imp;


import android.content.Context;
import android.util.Log;
import com.xiuyou.tracksdk.http.BaseCallback;
import com.xiuyou.tracksdk.http.ErrorMethod;
import com.xiuyou.tracksdk.http.HttpManager;
import com.xiuyou.tracksdk.http.NetWorkVerdict;
import com.xiuyou.tracksdk.parse.CommonTrackParse;
import com.xiuyou.tracksdk.parse.HistoryParse;
import com.xiuyou.tracksdk.tracksdk.module.HistoryPoint;
import com.xiuyou.tracksdk.tracksdk.module.ILocation;
import com.xiuyou.tracksdk.tracksdk.module.TrackRequest;
import com.xiuyou.tracksdk.tracksdk.utils.Config;
import com.xiuyou.tracksdk.tracksdk.module.BaseResult;
import com.xiuyou.tracksdk.tracksdk.protocol.CallBack;
import com.xiuyou.tracksdk.tracksdk.protocol.TrackProtocol;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by lhy on 2016/6/13.
 */
public class ITrackProtocol implements TrackProtocol {
    @Override
    public void addpoint(Context mcontext, final ILocation iLocation, final CallBack callBack) {
        Map<String, String> params = new HashMap<String, String>();
        params.put("ak", iLocation.getAk());
        params.put("entity_name", iLocation.getEntity_name());
        params.put("service_id", iLocation.getService_id());
        params.put("latitude", String.valueOf(iLocation.getLatitude()));
        params.put("longitude", String.valueOf(iLocation.getLongitude()));
        params.put("coord_type", iLocation.getCoord_type());
        long time = Long.valueOf(iLocation.getLoc_time())/1000;
        params.put("loc_time", String.valueOf(time));
        boolean isNetActive = NetWorkVerdict.isNetworkAvailable(mcontext);
        if(!isNetActive){
            callBack.onNetError(ErrorMethod.NET_NET_CONNECT.getValue());
            return;
        }
        String add_point_url = Config.BASE_URL+Config.ADD_POINT;
        HttpManager.getInstance(mcontext).doPost(add_point_url, params, new BaseCallback<BaseResult>() {
            @Override
            public void sucess(BaseResult baseResult) {
                callBack.onFinsh(baseResult);
            }

            @Override
            public void error(Exception e, String message) {
                callBack.onFailuer(message);
            }

            @Override
            public void serverError(String message) {
                callBack.onFailuer(message);
            }
        }, new CommonTrackParse());
    }

    @Override
    public <T extends BaseResult> void addPoints(Context mcontext, List<ILocation> iLocationList, CallBack<T> callBack) {
        //判断网络状况
        boolean isNetActive = NetWorkVerdict.isNetworkAvailable(mcontext);
        Socket s = null;
        if(!isNetActive){
            callBack.onNetError(ErrorMethod.NET_NET_CONNECT.getValue());
            return;
        }
        List<ILocation> iLocations = null;
//        String s1 = "{\"ak\":\"ec85d3648154874552835438ac6a02b2\",\"service_id\":\"100019\",\"entity_name\":\"测试汽车\",\"latitude\":\"39.905501\",\"longitude\":\"116.123456\",\"coord_type\":\"2\",\"loc_time\":\"1463564671\"}";
        try {
            iLocations = new ArrayList<ILocation>();
            s = new Socket(Config.HOST, Config.PORT);
            for(ILocation iLocation:iLocationList){
                String json = actionSocket(ILocation.toJson(iLocation),s);
                int status = parStatus(json);
                if(status == 0){
                    iLocations.add(iLocation);
                }
            }
            callBack.atchUpload(iLocations);
        } catch (Exception e) {
            callBack.atchUpload(iLocations);
            callBack.onFailuer(e.getMessage());
            Log.e("socket错误日志",e.getMessage());
        }finally {
            if(s != null && !s.isClosed()){
                try {
                    s.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public <T extends HistoryPoint> void gethistory(Context mcontext, TrackRequest trackRequest,final CallBack<T> callBack) {
        Map<String, String> params = new HashMap<String, String>();
        params.put("ak",trackRequest.getAk());
        params.put("service_id",trackRequest.getService_id());
        params.put("start_time",trackRequest.getStart_time());
        params.put("end_time",trackRequest.getEnd_time());
        params.put("entity_name",trackRequest.getEntity_name());
        params.put("sort_type",String.valueOf(trackRequest.getSort_type()));
        params.put("simple_return",String.valueOf(trackRequest.getSimple_return()));
        params.put("is_processed",String.valueOf(trackRequest.getIs_processed()));
        params.put("page_index",String.valueOf(trackRequest.getPage_index()));
        params.put("page_size",String.valueOf(trackRequest.getPage_size()));

        boolean isNetActive = NetWorkVerdict.isNetworkAvailable(mcontext);
        if(!isNetActive){
            callBack.onNetError(ErrorMethod.NET_NET_CONNECT.getValue());
            return;
        }

        String history_point_url = Config.BASE_URL+Config.GET_HISTORY;
        HttpManager.getInstance(mcontext).doGet(history_point_url,params,new BaseCallback<HistoryPoint>(){

            @Override
            public void sucess(HistoryPoint historyPoint) {
                callBack.onFinsh((T) historyPoint);
            }

            @Override
            public void error(Exception e, String message) {
                callBack.onFailuer(message);
            }

            @Override
            public void serverError(String message) {
                callBack.onFailuer(message);
            }
        },new HistoryParse());
    }

    public String actionSocket(String s1,Socket socket) throws Exception {
        byte[] b1 = s1.getBytes();
        byte[] b = intToByteArray1(b1.length);
        byte[] b2 = new byte[b.length + b1.length];
        System.arraycopy(b, 0, b2, 0, b.length);
        System.arraycopy(b1, 0, b2, b.length, b1.length);
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.write(b2);
        dos.flush();
        InputStream in = socket.getInputStream();
        DataInputStream dis = new DataInputStream(in);
        byte[] rheadb = new byte[4];
        dis.read(rheadb);
        int rlen=byteToInt2(rheadb);
        byte[] buffer = new byte[1024];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (int i = dis.read(buffer); i > -1; i = dis.read(buffer)) {
            baos.write(buffer, 0, i);
            rlen -= i;
            if (rlen == 0)
                break;
        }
        byte[] result = baos.toByteArray();
        String resultStr = new String(result);
        baos.flush();
        baos.close();
        Log.e("socket结果是",resultStr);
        return resultStr;
    }

    /**
     * 获取状态
     * @return
     * @throws JSONException
     */
    public int parStatus(String json) throws JSONException {
        JSONObject jsonObject = new JSONObject(json);
        int status = jsonObject.getInt("status");
        return status;
    }

    public static int byteToInt2(byte[] b) {
        int mask = 0xff;
        int temp = 0;
        int n = 0;
        for (int i = 0; i < 4; i++) {
            n <<= 8;
            temp = b[i] & mask;
            n |= temp;
        }
        return n;
    }

    public static byte[] intToByteArray1(int i) {
        byte[] result = new byte[4];
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }

}
